package ldh.im.admin.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.text.WordRenderer;
import com.google.code.kaptcha.util.Config;
import com.google.code.kaptcha.util.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.util.Properties;
import java.util.Random;

@Configuration
public class KcapricaConfig {

    @Bean
    public DefaultKaptcha kcaptcha() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "yes");
        properties.setProperty("kaptcha.border.color", "105,179,90");
//        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        properties.setProperty("kaptcha.image.width", "125");
        properties.setProperty("kaptcha.image.height", "45");
        properties.setProperty("kaptcha.textproducer.font.size", "40");
        properties.setProperty("kaptcha.session.key", "code");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体");
        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple"); // WaterRipple  ShadowGimpy  FishEyeGimpy
        properties.setProperty("kaptcha.noise.color", "black");
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
//        properties.setProperty("kaptcha.background.clear.from", "185,56,213");
//        properties.setProperty("kaptcha.background.clear.to", "white");
        properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
        properties.setProperty("kaptcha.word.impll", "ldh.oauth.configuration.KcapricaConfig.MyDefaultWordRenderer");

        Config config = new Config(properties) {
            Random random = new Random();
            public Color getNoiseColor() {
                return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
            }

            public Color getTextProducerFontColor() {
                return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
            }
        };
        defaultKaptcha.setConfig(config);

//        String text = defaultKaptcha.createText();
//        BufferedImage bufferedImage = defaultKaptcha.createImage(text);
//        WaterRipple waterRipple = new WaterRipple();
//        waterRipple.setConfig(new DefaultNoise());
//        return waterRipple.getDistortedImage(bufferedImage);
        return defaultKaptcha;
    }

    public static class MyDefaultWordRenderer extends Configurable implements WordRenderer {
        public MyDefaultWordRenderer() {
        }

        public BufferedImage renderWord(String word, int width, int height) {
            int fontSize = this.getConfig().getTextProducerFontSize();
            Font[] fonts = this.getConfig().getTextProducerFonts(fontSize);
            Color color = this.getConfig().getTextProducerFontColor();
            int charSpace = this.getConfig().getTextProducerCharSpace();
            BufferedImage image = new BufferedImage(width, height, 2);
            Graphics2D g2D = image.createGraphics();
            g2D.setColor(color);
            RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
            g2D.setRenderingHints(hints);
            FontRenderContext frc = g2D.getFontRenderContext();
            Random random = new Random();
            int startPosY = (height - fontSize) / 5 + fontSize;
            char[] wordChars = word.toCharArray();
            Font[] chosenFonts = new Font[wordChars.length];
            int[] charWidths = new int[wordChars.length];
            int widthNeeded = 0;

            int startPosX;
            for(startPosX = 0; startPosX < wordChars.length; ++startPosX) {
                chosenFonts[startPosX] = fonts[random.nextInt(fonts.length)];
                char[] charToDraw = new char[]{wordChars[startPosX]};
                GlyphVector gv = chosenFonts[startPosX].createGlyphVector(frc, charToDraw);
                charWidths[startPosX] = (int)gv.getVisualBounds().getWidth();
                if(startPosX > 0) {
                    widthNeeded += 5;
                }

                widthNeeded += charWidths[startPosX];
            }

            startPosX = (width - widthNeeded) / 2;

            for(int i = 0; i < wordChars.length; ++i) {
                g2D.setFont(chosenFonts[i]);
                char[] charToDraw = new char[]{wordChars[i]};
                g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX, startPosY);
                startPosX = startPosX + charWidths[i] + charSpace;
            }

            return image;
        }
    }
}
